home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
plan
/
src
/
mondraw.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
23KB
|
820 lines
/*
* Main calendar window widgets.
*
* clicked_calendar(x, y) Press in calendar day box detected,
* pop up a one-day list menu
* draw_month_year() Draw the month and year into the
* main calendar window
* draw_calendar() Draw day grid into the main calendar
* window
* draw_day(day) Draw one day box into the day grid
* in the main calendar window
* draw_day_notes(day) Draw just the notes under the day
* number into a day box
*
* date_to_time(day, month, year, wkday, yday, weeknum)
* Returns day/month/year as # of secs
* since 1/1/70, the weekday (0..6), the
* julian date (0..365), and the week #.
* day_to_pos(x, y, day) Return the position of the day box
* for a particular day.
* pos_to_day(day, x, y) Reverse operation, convert position
* to day number.
*/
#include <time.h>
#include <Xm/Xm.h>
#ifdef JAPAN
#include <jctype.h>
#include <locale.h>
#endif
#include "cal.h"
#undef FULLWEEKS /* if this is defined, the first complete week in */
/* January is counted as week 1. If it is undefined, */
/* the first partial week is counted as 1. */
extern char *mknotestring(), *mktimestring();
extern char *parse_holidays();
extern time_t tm_to_time();
extern struct tm *time_to_tm();
extern time_t get_time();
extern BOOL lookup_entry(), lookup_next_entry();
static BOOL set_day_bkg_color();
time_t date_to_time();
#ifdef JAPAN
static int mixedstrtok();
extern char *localename; /* locale name */
extern unsigned short (*kanji2jis)(); /* kanji2jis == euc2jis or sjis2jis */
#endif
extern Display *display; /* everybody uses the same server */
extern GC jgc, gc; /* graphic context, Japanese and std */
extern XFontStruct *font[NFONTS]; /* fonts: FONT_* */
extern struct mainmenu mainmenu; /* all important main window widgets */
extern struct config config; /* global configuration data */
extern int curr_month; /* month being displayed, 0..11 */
extern int curr_year; /* year being displayed, since 1900 */
extern time_t curr_week; /* week being displayed, time in sec */
extern struct list *mainlist; /* list of all schedule entries */
extern struct holiday holiday[366]; /* info for each day, separate for */
extern struct holiday sm_holiday[366];/* full-line texts under, and small */
extern short monthbegin[12]; /* julian date each month begins with*/
extern short monthlen[]; /* length of each month */
/* most recent popup made for: (only */
/* used to keep track of yellow box) */
int edit_month; /* month being edited, 0..11 */
int edit_year; /* year being edited, since 1900 */
int edit_day; /* day being edited, 1..31 or 0 */
extern char *weekday_name[];
extern char *monthname[];
/*
* got a click in the calendar area. If it's in a grid box with a valid
* day init, "edit" it by storing its day number in the edit_* variables.
* The previously edited day, and the new edited day are redrawn to move
* the yellow highlight. If the user clicked to the left of the calendar,
* create a week view.
* Also, create a day popup menu.
*/
clicked_calendar(x, y)
int x, y; /* pixel pos clicked */
{
int day;
time_t time; /* time of day box, in sec */
int sm = config.smallmonth;
if (x < config.calbox_marg[sm] + config.calbox_arrow[sm]) {
struct tm tm;
int xtest, ytest;
y -= config.calbox_marg[sm] + config.calbox_title[sm];
y /= config.calbox_ys[sm];
(void)day_to_pos(&xtest, &ytest, 1);
tm.tm_year = curr_year;
tm.tm_mon = curr_month;
tm.tm_mday = 7 * y - xtest +1;
tm.tm_hour = 0;
tm.tm_min = 0;
tm.tm_sec = 0;
if (tm.tm_mday < 1) {
if (!tm.tm_mon--)
return;
tm.tm_mday += monthlen[tm.tm_mon] +
(tm.tm_mon==1 && !(tm.tm_year&3));
}
if ((time = tm_to_time(&tm)) != (time_t)-1) {
curr_week = time;
create_week_menu();
}
return;
}
if (!pos_to_day(&day, x, y) || day == edit_day)
return;
if (edit_day) {
int oldday = edit_day;
edit_day = 0;
draw_day(oldday);
draw_year_day(oldday, edit_month, edit_year);
draw_week_day(oldday, edit_month, edit_year);
}
edit_day = day;
edit_month = curr_month;
edit_year = curr_year;
draw_day(edit_day);
draw_year_day(edit_day, edit_month, edit_year);
draw_week_day(edit_day, edit_month, edit_year);
if (time = date_to_time(day, curr_month, curr_year, 0, 0, 0))
create_list_popup(mainlist, time,
(time_t)0, (char *)0, (struct entry *)0);
}
/*-------------------------------------------------- drawing ----------------*/
/*
* draw the weekday names, depending on the Sunday-first flag
*/
draw_month_year()
{
print_button(mainmenu.month, monthname[curr_month]);
print_button(mainmenu.year, "%d", curr_year+1900);
}
/*
* draw all day boxes
*/
draw_calendar()
{
register struct config *c = &config;
Window window;
XRectangle rects[7+8], *r = rects;
XPoint point[4];
int i, j;
int sm = c->smallmonth;
if (!mainmenu.cal)
return;
window = XtWindow(mainmenu.cal);
set_color(COL_CALBACK); /* clear */
XFillRectangle(display, window, gc, 0, 0,
2*c->calbox_marg[sm] + c->calbox_xs[sm] * 7
+ c->calbox_arrow[sm],
2*c->calbox_marg[sm] + c->calbox_ys[sm] * 6
+ c->calbox_title[sm]);
/* vert lines */
for (i=0; i < 8; i++, r++) {
r->x = c->calbox_marg[sm] + i * c->calbox_xs[sm]
+ c->calbox_arrow[sm];
r->y = c->calbox_marg[sm] + c->calbox_title[sm];
r->width = 3;
r->height = c->calbox_ys[sm] * 6;
}
/* horz lines */
for (i=0; i < 7; i++, r++) {
r->x = c->calbox_marg[sm] + c->calbox_arrow[sm];
r->y = c->calbox_marg[sm] + c->calbox_title[sm]
+ c->calbox_ys[sm] * i;
r->width = c->calbox_xs[sm] * 7 + 3;
r->height = 3;
}
set_color(COL_GRID);
XFillRectangles(display, window, gc, rects, 7+8);
set_color(COL_CALFRAME);
XDrawRectangle(display, window, gc,
c->calbox_marg[sm] + c->calbox_arrow[sm] -1,
c->calbox_marg[sm] + c->calbox_title[sm] -1,
c->calbox_xs[sm] * 7 + 4,
c->calbox_ys[sm] * 6 + 4);
point[3].x = /* week call arrows */
point[0].x =
point[1].x = c->calbox_marg[sm]/2 +1;
point[2].x = point[0].x + c->calbox_arrow[sm] -1;
point[2].y = c->calbox_marg[sm] + c->calbox_title[sm]
+ c->calbox_ys[sm] / 2;
point[3].y =
point[0].y = point[2].y - (point[2].x - point[0].x);
point[1].y = point[2].y + (point[2].x - point[0].x);
if (c->calbox_arrow[sm] > 3)
for (i=0; i < 6; i++) {
set_color(COL_CALSHADE);
XFillPolygon(display, window, gc, point, 3, Convex,
CoordModeOrigin);
set_color(COL_STD);
XDrawLines(display, window, gc, point, 4,
CoordModeOrigin);
point[0].y += c->calbox_ys[sm];
point[1].y += c->calbox_ys[sm];
point[2].y += c->calbox_ys[sm];
point[3].y += c->calbox_ys[sm];
}
set_color(COL_STD);
/* weekday names */
j = c->sunday_first ? 6 : 0;
XSetFont(display, gc, font[sm ? FONT_NOTE : FONT_STD]->fid);
for (i=0; i < 7; i++, j++)
XDrawString(display, window, gc,
c->calbox_marg[sm] + c->calbox_arrow[sm]
+ c->calbox_xs[sm] * i,
c->calbox_marg[sm] + c->calbox_title[sm] * 3/4,
weekday_name[j%7], strlen(weekday_name[j%7]));
for (i=1; i < 32; i++)
draw_day(i);
}
/*
* draw one day box.
*/
draw_day(day)
int day; /* 1..31 */
{
Window window;
char buf[200]; /* julian, weeknum, holiday */
int x, y; /* position in calendar */
int jul; /* julian date of daybox */
int daynum_xs; /* width of day# in pixels */
BOOL leftedge; /* in leftmost daybox? */
BOOL weekend; /* saturday or sunday? */
BOOL today; /* is this today's box? */
struct holiday *hp, *shp; /* to check for holidays */
char *errmsg; /* holiday parser error */
int sm = config.smallmonth;
#ifdef JAPAN
int ji, jlen, jpixlen, jdeltax;
XChar2b jstr[50];
#endif
if (!mainmenu.cal || !day_to_pos(&x, &y, day))
return;
window = XtWindow(mainmenu.cal);
weekend = x == 6 || x == (config.sunday_first ? 0 : 5);
leftedge = x == 0;
daynum_xs = 5 + 2*font[FONT_DAY+sm]->per_char
['0'- font[FONT_DAY+sm]->min_char_or_byte2].width;
x = config.calbox_marg[sm] + x * config.calbox_xs[sm] + 3 +
config.calbox_arrow[sm];
y = config.calbox_marg[sm] + y * config.calbox_ys[sm] + 3 +
config.calbox_title[sm];
today = set_day_bkg_color(day);
XFillRectangle(display, window, gc, x, y, config.calbox_xs[sm]-3,
config.calbox_ys[sm]-3);
sprintf(buf, "%d", day);
XSetFont(display, gc, font[FONT_DAY+sm]->fid);
if (errmsg = parse_holidays(curr_year, FALSE))
create_error_popup(mainmenu.cal, 0, errmsg);
jul = monthbegin[curr_month] + day-1 +(curr_month>1 && !(curr_year&3));
hp = &holiday[jul];
shp = &sm_holiday[jul];
set_color( hp->daycolor ? hp->daycolor :
shp->daycolor ? shp->daycolor :
weekend ? COL_WEEKEND : COL_WEEKDAY);
XDrawString(display, window, gc,
x+2, y+font[FONT_DAY+sm]->max_bounds.ascent, buf, strlen(buf));
if (config.julian || config.weeknum) {
int wkday, weeknum;
(void)date_to_time(day, curr_month, curr_year,
&wkday, &jul, &weeknum);
*buf = 0;
if (config.weeknum && leftedge)
sprintf(buf, "(%d)", weeknum+1);
if (config.julian)
sprintf(buf+strlen(buf), "%d", jul+1);
truncate_string(buf, config.calbox_xs[sm] - 3 - daynum_xs,
FONT_NOTE);
XSetFont(display, gc, font[FONT_NOTE]->fid);
XDrawString(display, window, gc,
x + daynum_xs,
y + font[FONT_NOTE]->max_bounds.ascent,
buf, strlen(buf));
}
if (shp->string && (!config.julian && !config.weeknum ||
font[FONT_DAY+sm]->max_bounds.ascent >
font[FONT_NOTE]->max_bounds.ascent * 2)) {
strncpy(buf, shp->string, sizeof(buf)-1);
buf[sizeof(buf)-1] = 0;
#ifndef JAPAN
truncate_string(buf, config.calbox_xs[sm] - 3 - daynum_xs,
FONT_NOTE);
#endif
if (shp->stringcolor)
set_color(shp->stringcolor);
else if (shp->daycolor)
set_color(shp->daycolor);
XSetFont(display, gc, font[FONT_NOTE]->fid);
#ifdef JAPAN
XSetFont(display, jgc, font[FONT_JNOTE]->fid);
ji = mixedstrtok(jstr, buf);
jpixlen = config.calbox_xs[sm] - 3 - daynum_xs;
jdeltax = 0;
do {
if (ji < 0) {
fprintf(stderr, "String conversion error.\n");
break;
}
if (ji == 0)
break;
jlen = strlen((char *)jstr);
if (ji == 1) {
ji = XTextWidth(font[FONT_NOTE],
(char *)jstr, jlen);
if (jpixlen < ji)
jlen *= (double)jpixlen/(double)ji;
XDrawString(display, window, gc,
x + daynum_xs + jdeltax,
y + font[FONT_DAY+sm]
->max_bounds.ascent,
(char *)jstr, jlen);
} else {
ji = XTextWidth16(font[FONT_JNOTE],
(char *)jstr, jlen/2);
if (jpixlen < ji)
jlen *= (double)jpixlen/(double)ji;
XDrawString16(display, window, jgc,
x + daynum_xs + jdeltax,
y + font[FONT_DAY+sm]
->max_bounds.ascent,
jstr, jlen/2);
}
jdeltax += ji;
jpixlen -= ji;
} while (jpixlen > 0 && (ji = mixedstrtok(jstr, NULL)));
#else
XDrawString(display, window, gc,
x + daynum_xs,
y + font[FONT_DAY+sm]->max_bounds.ascent,
buf, strlen(buf));
#endif
}
set_color(COL_STD);
draw_day_notes(day);
if (today && config.frame_today) {
XDrawRectangle(display, window, gc, x+1, y+1,
config.calbox_xs[sm]-6, config.calbox_ys[sm]-6);
XDrawRectangle(display, window, gc, x+2, y+2,
config.calbox_xs[sm]-8, config.calbox_ys[sm]-8);
}
}
/*
* draw (or undraw) the notes in a day box. Looks up the day in the database.
*/
draw_day_notes(day)
int day; /* 1..31 */
{
BOOL today; /* TRUE: it's today's daybox */
struct tm *tm; /* for daylight-saving tzone */
time_t tod; /* current time-of-day */
time_t daytime; /* time of day box, in sec */
BOOL found; /* TRUE if lookup succeeded */
struct lookup lookup; /* result of entry lookup */
register struct entry *ep; /* ptr to entry in mainlist */
int x, y; /* position in calendar */
int xo, i; /* for aligning ':' in time */
int ye; /* bottom limit of day box */
int ys; /* height of a text line */
char buf[100]; /* string buffer (time/note) */
int jul; /* julian date of daybox */
struct holiday *hp; /* holiday info for this day */
char *errmsg; /* parser error */
Window window;
int sm = config.smallmonth;
#ifdef JAPAN
int ji, jlen, jpixlen, jdeltax;
XChar2b jstr[50];
#endif
if (!mainmenu.cal)
return;
window = XtWindow(mainmenu.cal);
tod = get_time();
tm = time_to_tm(tod);
today = day == tm->tm_mday &&
curr_month == tm->tm_mon &&
curr_year == tm->tm_year;
if (!day_to_pos(&x, &y, day) ||
!(daytime = date_to_time(day, curr_month, curr_year, 0, 0, 0)))
return;
x = config.calbox_marg[sm] + x * config.calbox_xs[sm] + 3 +
config.calbox_arrow[sm];
y = config.calbox_marg[sm] + y * config.calbox_ys[sm] + 3 +
config.calbox_title[sm];
ye = y + config.calbox_ys[sm] - 3;
#ifdef JAPAN
ys = font[FONT_JNOTE]->max_bounds.ascent +
font[FONT_JNOTE]->max_bounds.descent/2;
if (ys < font[FONT_NOTE]->max_bounds.ascent +
font[FONT_NOTE]->max_bounds.descent/2)
#endif
ys = font[FONT_NOTE] ->max_bounds.ascent +
font[FONT_NOTE] ->max_bounds.descent/2;
y += font[FONT_DAY+sm]->max_bounds.ascent + (ye - y) % ys / 2;
(void)set_day_bkg_color(day);
XFillRectangle(display, window, gc, x,y, config.calbox_xs[sm]-3, ye-y);
XSetFont(display, gc, font[FONT_NOTE]->fid);
#ifdef JAPAN
XSetFont(display, jgc, font[FONT_JNOTE]->fid);
#endif
if (errmsg = parse_holidays(curr_year, FALSE))
create_error_popup(mainmenu.cal, 0, errmsg);
jul = monthbegin[curr_month] + day-1 + (curr_month>1 && !(curr_year&3));
hp = &holiday[jul];
#ifdef JAPAN
if (hp->string && *hp->string &&
y + ((font[FONT_NOTE ]->max_bounds.descent <
font[FONT_JNOTE]->max_bounds.descent ?
font[FONT_JNOTE]->max_bounds.descent :
font[FONT_NOTE ]->max_bounds.descent)<<2) <= ye){
y += (font[FONT_NOTE ]->max_bounds.ascent <
font[FONT_JNOTE]->max_bounds.ascent) ?
font[FONT_JNOTE]->max_bounds.ascent :
font[FONT_NOTE ]->max_bounds.ascent;
set_color(hp->stringcolor ? hp->stringcolor : COL_NOTE);
ji = mixedstrtok(jstr, hp->string);
jpixlen = config.calbox_xs[sm] - 3;
jdeltax = 0;
do {
if (ji < 0) {
fprintf(stderr, "String conversion error.\n");
break;
}
if (ji == 0)
break;
jlen = strlen((char *)jstr);
if (ji == 1) {
ji = XTextWidth(font[FONT_NOTE],
(char *)jstr, jlen);
if (jpixlen < ji)
jlen *= (double)jpixlen/(double)ji;
XDrawString(display, window, gc, x+jdeltax+2,
y, (char *)jstr, jlen);
} else {
ji = XTextWidth16(font[FONT_JNOTE],
(char *)jstr, jlen/2);
if (jpixlen < ji)
jlen *= (double)jpixlen/(double)ji;
XDrawString16(display, window, jgc,
x+jdeltax+2, y, jstr, jlen/2);
}
jdeltax += ji;
jpixlen -= ji;
} while (jpixlen > 0 && (ji = mixedstrtok(jstr, NULL)));
y += (font[FONT_NOTE ]->max_bounds.descent <
font[FONT_JNOTE]->max_bounds.descent) ?
font[FONT_JNOTE]->max_bounds.descent/2 :
font[FONT_NOTE ]->max_bounds.descent/2;
}
#else
if (hp->string && *hp->string &&
y + font[FONT_NOTE]->max_bounds.descent
+ font[FONT_NOTE]->max_bounds.descent <= ye){
strncpy(buf, hp->string, sizeof(buf)-1);
truncate_string(buf, config.calbox_xs[sm] - 3, FONT_NOTE);
y += font[FONT_NOTE]->max_bounds.ascent;
set_color(hp->stringcolor ? hp->stringcolor : COL_NOTE);
XDrawString(display, window, gc, x+2, y, buf, strlen(buf));
y += font[FONT_NOTE]->max_bounds.descent/2;
}
#endif
found = lookup_entry(&lookup, mainlist, daytime, TRUE, FALSE);
for (; found; found = lookup_next_entry(&lookup)) {
ep = &mainlist->entry[lookup.index];
if (ep->note && (*ep->note == '-' || *ep->note == '='))
continue;
if (lookup.index >= mainlist->nentries ||
lookup.trigger < daytime ||
lookup.trigger >= daytime + 86400)
break;
if (today && config.nopast &&
lookup.trigger < tod &&
!ep->notime)
continue;
if (y + font[FONT_NOTE]->max_bounds.descent
+ font[FONT_NOTE]->max_bounds.descent > ye) {
int xe = x + config.calbox_xs[sm] -3;
set_color(COL_NOTE);
XFillRectangle(display, window, gc, xe-4, ye-3, 2, 2);
XFillRectangle(display, window, gc, xe-8, ye-3, 2, 2);
XFillRectangle(display, window, gc, xe-12, ye-3, 2, 2);
break;
}
if (ep->notime)
sprintf(buf, "%.90s", mknotestring(ep));
else
sprintf(buf, "%s %.90s", mktimestring(lookup.trigger,
FALSE), mknotestring(ep));
#ifdef JAPAN
y += (font[FONT_NOTE ]->max_bounds.ascent <
font[FONT_JNOTE]->max_bounds.ascent) ?
font[FONT_JNOTE]->max_bounds.ascent :
font[FONT_NOTE ]->max_bounds.ascent;
set_color(ep->suspended ? COL_NOTEOFF : COL_NOTE);
ji = mixedstrtok(jstr, buf);
jpixlen = config.calbox_xs[sm] - 3;
jdeltax = 0;
do {
if (ji < 0) {
fprintf(stderr, "String conversion error.\n");
break;
}
if (ji == 0)
break;
jlen = strlen((char *)jstr);
if (ji == 1) {
ji = XTextWidth(font[FONT_NOTE],
(char *)jstr, jlen);
if (jpixlen < ji)
jlen *= (double)jpixlen/(double)ji;
XDrawString(display, window, gc, x+jdeltax+2,
y, (char *)jstr, jlen);
} else {
ji = XTextWidth16(font[FONT_JNOTE],
(char *)jstr, jlen/2);
if (jpixlen < ji)
jlen *= (double)jpixlen/(double)ji;
XDrawString16(display, window, jgc,
x+jdeltax+2, y, jstr, jlen/2);
}
jdeltax += ji;
jpixlen -= ji;
} while (jpixlen > 0 && (ji = mixedstrtok(jstr, NULL)));
#else
truncate_string(buf, config.calbox_xs[sm] - 5, FONT_NOTE);
y += font[FONT_NOTE]->max_bounds.ascent;
set_color(ep->suspended ? COL_NOTEOFF : COL_NOTE);
i = font[FONT_NOTE]->min_char_or_byte2;
xo = font[FONT_NOTE]->per_char['0' - i].width -
font[FONT_NOTE]->per_char[*buf - i].width;
if (xo < 0) xo = 0;
XDrawString(display, window, gc, x+2+xo, y, buf, strlen(buf));
#endif
y += font[FONT_NOTE]->max_bounds.descent/2;
}
set_color(COL_STD);
}
/*
* truncate <string> such that it is not longer than <len> pixels when
* drawn with font <sfont>, by storing \0 somewhere in the string.
*/
truncate_string(string, len, sfont)
register unsigned char *string; /* string to truncate */
register int len; /* max len in pixels */
int sfont; /* font of string */
{
while (*string) {
len -= font[sfont]->per_char
[*string - font[sfont]->min_char_or_byte2].width;
if (len < 0)
*string = 0;
else
string++;
}
}
static BOOL set_day_bkg_color(day)
int day; /* 1..31 */
{
struct tm *tm;
tm = time_to_tm(get_time());
if (day == edit_day &&
curr_year == edit_year &&
curr_month == edit_month) {
set_color(COL_CALACT);
return(FALSE);
} else if (day == tm->tm_mday &&
curr_month == tm->tm_mon &&
curr_year == tm->tm_year) {
set_color(COL_CALTODAY);
return(TRUE);
} else {
set_color(COL_CALSHADE);
return(FALSE);
}
}
/*-------------------------------------------------- low-level --------------*/
/*
* day/month/year to time. Return 0 if something is wrong.
* Also return the weekday, julian date, and week number of that date.
* Note that *wkday counts from 0=sunday to 6=saturday.
*/
time_t date_to_time(day, month, year, wkday, julian, weeknum)
int day, month, year, *wkday, *julian, *weeknum;
{
struct tm tm;
time_t time;
tm.tm_sec = 0;
tm.tm_min = 0;
tm.tm_hour = 0;
tm.tm_mday = day;
tm.tm_mon = month;
tm.tm_year = year;
time = tm_to_time(&tm);
if (wkday)
*wkday = tm.tm_wday;
if (julian)
*julian = tm.tm_yday;
if (weeknum)
#ifdef FULLWEEKS
*weeknum = tm.tm_yday / 7;
#else
*weeknum = tm.tm_yday ? ((tm.tm_yday - 1) /7) + 1: 0;
#endif
return(time == -1 || day != tm.tm_mday ? 0 : time);
}
day_to_pos(x, y, day)
int *x, *y; /* returned box, 0..6/0..5 */
int day; /* 1..31 */
{
int wkday;
if (!date_to_time(day, curr_month, curr_year, &wkday, 0, 0))
return(FALSE);
*x = config.sunday_first ? wkday : (wkday + 6) % 7;
*y = (day-1 - *x + 6) / 7;
return(TRUE);
}
pos_to_day(day, x, y)
int *day; /* returned day #, 1..31 */
int x, y; /* pixel pos in drawable */
{
int xtest, ytest;
int sm = config.smallmonth;
(void)day_to_pos(&xtest, &ytest, 1);
x -= config.calbox_marg[sm] + config.calbox_arrow[sm];
y -= config.calbox_marg[sm] + config.calbox_title[sm];
if (x < 0 || y < 0)
return(FALSE);
x /= config.calbox_xs[sm];
y /= config.calbox_ys[sm];
*day = y * 7 + x - xtest + 1;
if (*day < 1)
return(FALSE);
return(day_to_pos(&xtest, &ytest, *day));
}
/*
* the rest of this file is for Japanese version only. Written by Ogura
* Yoshito, like everything else enclosed in #ifdef JAPAN and #endif.
*/
#ifdef JAPAN
static int mixedstrtok(jisstr, sjstr)
char *jisstr, *sjstr;
{
static int stat;
static unsigned char *sptr = NULL;
unsigned char *dptr = (unsigned char *)jisstr;
unsigned short wc;
int prev_ct = CT_ASC;
if (sjstr != NULL)
stat = chkctype(*(char *)
(sptr = (unsigned char *)sjstr), CT_ASC);
if (sptr == NULL) {
*dptr = '\0';
return (-1); /* Illegal pointer. */
}
while (*sptr != '\0') {
switch (prev_ct = chkctype(*sptr, prev_ct)) {
case CT_ASC:
if (stat != CT_ASC)
goto STATCHG;
*dptr++ = *sptr++;
break;
case CT_KJ1:
if (stat == CT_ASC)
goto STATCHG;
wc = *sptr++ << 8;
break;
case CT_KJ2:
if (stat == CT_ASC)
goto STATCHG;
wc |= *sptr++;
wc = (*kanji2jis)(wc);
/* kanji2jis == euc2jis or sjis2jis */
*dptr++ = wc >> 8;
*dptr++ = wc;
break;
default:
*dptr = '\0';
return (-1); /* Parse error. */
}
}
STATCHG:
*dptr = '\0';
if (jisstr != (char *)dptr) {
/* Bit1 == 1 if SJIS string is copied. */
wc = stat;
stat = prev_ct;
return (wc == CT_ASC) ? 1 : 2;
}
return 0;
}
int mixedstrlen_in_pixels(sjstr, stp, ascfont, jfont)
char *sjstr;
strpack *stp;
int ascfont, jfont;
{
register int jlen, plen = 0, i = 0, j = 0, k;
register unsigned char *cpyptr, *strpool = stp->strptr;
unsigned char jstr[100];
k = mixedstrtok(cpyptr = jstr, sjstr);
do {
if (k <= 0) {
if (k != 0)
fprintf(stderr, "String conversion error.\n");
stp[i].strptr = NULL;
break;
}
if (j+1+(jlen = stp[i].length = strlen(jstr))>=MAXPARTIALCHAR){
if (jlen = stp[i].length = (MAXPARTIALCHAR-j-1 & ~1)) {
for (stp[i].strptr = strpool + j;
j < MAXPARTIALCHAR-1; j++)
strpool[j] = *cpyptr++;
strpool[j] = '\0';
if (k == 1) {
stp[i].asciistr = True;
plen += stp[i].pixlen = XTextWidth(
font[ascfont], jstr, jlen);
} else {
stp[i].asciistr = False;
plen += stp[i].pixlen = XTextWidth16(
font[jfont],
(XChar2b *)jstr, jlen/2);
}
if (++i < MAXPARTIALSTRING)
stp[i].strptr = NULL;
} else
stp[i].strptr = NULL;
break;
}
stp[i].strptr = strpool + j;
while (*cpyptr != '\0')
strpool[j++] = *cpyptr++;
strpool[j++] = '\0';
if (k == 1) {
stp[i].asciistr = True;
plen += stp[i].pixlen = XTextWidth(font[ascfont],
jstr, jlen);
} else {
stp[i].asciistr = False;
plen += stp[i].pixlen = XTextWidth16(font[jfont],
(XChar2b * )jstr, jlen / 2);
}
} while (++i < MAXPARTIALSTRING &&
((k = mixedstrtok(cpyptr = jstr, NULL)) ||
((stp[i].strptr = NULL), 0)));
return plen;
}
#endif